package sdk

import (
	"fmt"
	"os"
	"path/filepath"
	"time"

	"Cosmos.Communication/internal/conf"
	"Cosmos.Communication/internal/service"
	kratoszap "github.com/go-kratos/kratos/contrib/log/zap/v2"
	"github.com/go-kratos/kratos/v2"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware/tracing"
	"github.com/go-kratos/kratos/v2/transport"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
)

var (
	name string

	version string

	id, _ = os.Hostname()

	Cleanup cleanup
)

type Role struct {
	*kratos.App
	service.Ability
}

type cleanup func()

func newRole(logger log.Logger, ability service.Ability, gs transport.Server) *Role {
	kratosApp := kratos.New(
		kratos.ID("ID"),
		kratos.Name("Name"),
		kratos.Version("Version"),
		kratos.Metadata(map[string]string{}),
		kratos.Logger(logger),
		kratos.Server(
			gs,
		),
	)

	return &Role{
		kratosApp,
		ability,
	}
}

func InitLogger(logFilePath string, maxSize, maxAge, maxBackups, logLevel int) (logger log.Logger) {
	if logFilePath == "" {
		logFilePath, _ = os.Getwd()
	}
	if maxSize == 0 {
		maxSize = 100
	}
	if maxAge == 0 {
		maxAge = 7
	}
	if maxBackups == 0 {
		maxBackups = 30
	}

	// 配置日志文件路径和文件名格式
	currentDate := time.Now().Format("2006-01-02")
	logFileName := fmt.Sprintf("cosmossdk_%s.log", currentDate)

	// 创建日志器
	lumberjackLogger := &lumberjack.Logger{
		Filename:   filepath.Join(logFilePath, logFileName),
		MaxSize:    maxSize,
		MaxAge:     maxAge,
		MaxBackups: maxBackups,
		LocalTime:  true,
		Compress:   false,
	}
	zapLogger := newZapLogger(lumberjackLogger, zap.NewAtomicLevelAt(zapcore.Level(logLevel)))

	logger = log.With(zapLogger,
		"caller", log.DefaultCaller,
		"service.id", id,
		"service.name", name,
		"service.version", version,
		"trace.id", tracing.TraceID(),
		"span.id", tracing.SpanID(),
	)

	log.SetLogger(logger)
	log.Info("日志模块启动完成")
	return
}

func CreateProcesorRole(conf *conf.Config, logger log.Logger) (role *Role) {
	var (
		err error
	)

	role, Cleanup, err = wireProcessor(conf, logger)
	if err != nil {
		log.Error("Init Error:", err)
		panic(err)
	}
	return
}

func (role *Role) RunRole() {
	var (
		err error
	)

	log.Info("启动监听服务")
	if err = role.Run(); err != nil {
		log.Error("监听服务启动失败:", err)
	}
}

// 创建新的 Zap Logger
func newZapLogger(lumberjackLogger *lumberjack.Logger, logLevel zap.AtomicLevel) *kratoszap.Logger {
	// 创建 Zap 核心
	core := zapcore.NewCore(
		zapcore.NewJSONEncoder(zapcore.EncoderConfig{
			TimeKey:        "Time",
			LevelKey:       "level",
			NameKey:        "logger",
			CallerKey:      "caller",
			FunctionKey:    zapcore.OmitKey,
			MessageKey:     "msg",
			StacktraceKey:  "stacktrace",
			LineEnding:     zapcore.DefaultLineEnding,
			EncodeLevel:    zapcore.LowercaseLevelEncoder,
			EncodeTime:     zapcore.RFC3339NanoTimeEncoder,
			EncodeDuration: zapcore.SecondsDurationEncoder,
			EncodeCaller:   zapcore.ShortCallerEncoder,
		}),
		zapcore.AddSync(lumberjackLogger),
		logLevel,
	)

	// 创建 Zap Logger
	z := zap.New(core)

	return kratoszap.NewLogger(z)
}
